<template>
    <div class="videoPlayer" ref="videoPlayer" @mousemove="dragVideo" @mouseup="progressUp">
        <video preload :autoPlay="option.autoPlay" :muted="option.muted" ref="video" @ended="videoEnd"></video>
        <div class="pc_controls_box">
            <p style="color: #ffffff">{{videoDetails}}</p>
            <div class="pc_controls">
                <!--进度条-->
                <div class="progress" @mousedown="progressDown" @click="progressClick">
                    <div class="progress_spot" ref="progress_spot"
                         :style="{left: videoDetails.currentTime + '%'}"></div>
                    <div class="progress_bar" :style="{width: videoDetails.currentTime + '%'}"></div>
                </div>
                <!--控制栏-->
                <div class="tool">
                    <div class="playBox">
                        <div @click="pausedChange(false)" v-show="videoDetails.paused"></div>
                        <div @click="pausedChange(true)" v-show="!videoDetails.paused"></div>
                    </div>
                    <div class="timeBox">
                        <span>{{videoDetails.videoTime}} / </span>
                        <span>{{videoDetails.lengthTime}}</span>
                    </div>
                    <div class="speedBox" @mouseover="speedListShow = true" @mouseout="speedListShow = false">
                        <div class="speedBoxBtn" @click="speedListShow = !speedListShow">倍数 {{videoDetails.speedKey}}
                        </div>
                        <div class="speedList" v-show="speedListShow">
                            <div @click="videoSpeedChange(item)" v-for="(item, index) in speed"
                                 :class="{active: item.value === videoDetails.speed}" :key="index">{{item.key}}
                            </div>
                        </div>
                    </div>
                    <div class="volumeBox">
                        <div :class="videoDetails.muted ? 'muted':'volumeBtn'" @click="mutedChange"></div>
                        <div class="volumeSetting">
                            <div class="lineBg" ref="volumeLine" @mousedown="volumeDown"
                                 @click="clickVolumeLine($event.target)">
                                <div class="line" :style="{height: videoDetails.volume * 100 +'%'}"></div>
                                <div class="spot" :style="{bottom: videoDetails.volume * 100 +'%'}"></div>
                            </div>
                            >
                        </div>
                    </div>
                    <div class="fullScreenBox" >
                        <div v-show="!videoDetails.isFullScreen" @click="openFullScreen"></div>
                        <div v-show="videoDetails.isFullScreen" @click="exitFullscreens"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
  import * as Hls from './hls.js'
  import * as Flv from './flv.js'

  export default {
    props: {
      options: {
        type: Object,
        default: () => {
          return {
            src: '',
            autoPlay: true
          }
        }
      }
    },
    data() {
      return {
        hls: null,
        video: null,
        videoDetails: {
          duration: 0, //视频长度
          videoTime: '00:00',
          currentTime: 0, //视频进度
          lengthTime: '00:00',
          paused: false, // 是否暂停
          speed: 1, // 播放速度
          speedKey: '1.0X',
          volume: 1, // 音量大小
          isFullScreen: false, //是否全屏
          muted: false //是否静音
        },
        option: {
          src: '',
          autoPlay: true,
          controls: false,
          muted: false
        },
        webInfo: {
          width: 0,
          height: 0
        },
        timer: null,
        isMouseDown: false,
        speedListShow: false,
        speed: [
          {
            key: '2.0X',
            value: 2
          },
          {
            key: '1.5X',
            value: 1.5
          },
          {
            key: '1.25X',
            value: 1.25
          },
          {
            key: '1.0X',
            value: 1
          }
        ],
        isVolumeDown: false //判断音量设置是否按下
      }
    },
    created() {
      this.option = Object.assign(this.option, this.options)
    },
    computed: {
      webState: function () {
        let type = 'transverse'
        let equipment = 'pc'
        const {width, height} = this.webInfo
        if (+width < 720) {
          equipment = 'mobile'
        } else {
          equipment = 'pc'
        }
        if (width <= height) {
          type = 'vertical'
        }
        return `${equipment}_${type}`
      }
    },
    methods: {
      DateFormat(date) {
        let hour = Math.floor(date / 3600)
        let minuts = Math.floor((date % 3600) / 60)
        let second = Math.floor(date % 60)
        if (second.toString().length < 2) {
          second = '0' + second.toString()
        }
        if (minuts.toString().length < 2) {
          minuts = '0' + minuts.toString()
        }
        if (hour.toString().length < 2) {
          hour = '0' + hour.toString()
        }
        return `${hour}:${minuts}:${second}`
      },
      getPcInfo() {
        const that = this
        let width = window.screen.availWidth
        let height = window.screen.availHeight
        onresize = function () {
          width = window.screen.availWidth
          height = window.screen.availHeight
          that.webInfo = {width, height}
        }
        that.webInfo = {width, height}
      },
      async play() {
        const that = this
        if (this.option.autoPlay) {
          try {
            await that.video.play()
          } catch (err) {
            that.video.muted = true
            that.videoDetails.muted = true
            await that.video.play()
          }
        }
      },
      // 修改播放状态
      pausedChange(state) {
        this.videoDetails.paused = state
        if (state) {
          clearTimeout(this.timer)
          this.video.pause()
        } else {
          console.log(this.videoDetails)
          this.play()
        }
      },
      getVideoDetails() {
        const data = Object.assign({}, this.getVideoDetails)
        // 当前进度
        const currentTime = this.video.currentTime
        data.currentTime = (currentTime / this.video.duration * 100).toFixed(2)
        data.videoTime = this.DateFormat(currentTime)
        // 视频长度
        data.duration = this.video.duration
        if (data.duration === 'infinity' || data.duration.toString() === 'NaN') {
          data.duration = 0
        }
        data.lengthTime = this.DateFormat(data.duration)
        // 视频播放状态
        data.paused = this.video.paused

        // 获取视频音量
        data.volume = this.video.volume

        // 获取视频声音状态
        data.muted = this.video.muted

        this.videoDetails = Object.assign(this.videoDetails, data)
        if (this.timer) clearTimeout(this.timer)
        this.timer = setTimeout(this.getVideoDetails, 500)
      },

      // 选择播放进度
      progressClick(e) {
        clearTimeout(this.timer)
        const data = Object.assign({}, this.videoDetails)
        data.currentTime = (e.x / this.video.clientWidth * 100).toFixed(2)
        this.video.currentTime = data.duration * e.x / this.video.clientWidth
        this.videoDetails = data
        this.getVideoDetails()
      },
      // 进度条拖动
      progressUp() {
        this.isMouseDown = false
        this.isVolumeDown = false
        this.getVideoDetails()
      },
      dragVideo(e) {
        if (this.isMouseDown) {
          this.progressClick(e)
        }
        // 如果是音量拖动
        if (this.isVolumeDown) {
          this.clickVolumeLine(e)
        }
      },
      progressDown() {
        clearTimeout(this.timer)
        this.isMouseDown = true
      },
      // 视频播放结束
      videoEnd() {
        clearTimeout(this.timer)
      },
      // 设置视频播放速度
      videoSpeedChange(speed) {
        this.video.playbackRate = speed.value
        this.videoDetails.speed = speed.value
        this.videoDetails.speedKey = speed.key
        this.speedListShow = false
      },

      // 设置音量
      // 点击设置音量
      clickVolumeLine(e) {
        const volumeLine = this.$refs.volumeLine
        if (e.offsetY > volumeLine.clientHeight) {
          return
        }
        if (this.isVolumeDown) {
          console.log(e)
          const data = Object.assign({}, this.videoDetails)
          const lineY = volumeLine.clientHeight - e.layerY
          const volume = (lineY / volumeLine.clientHeight).toFixed(2)
          this.video.volume = volume
          data.volume = volume
          this.videoDetails = data
        }
      },
      volumeDown() {
        this.isVolumeDown = true
      },
      //设置静音
      mutedChange() {
        const data = Object.assign({}, this.videoDetails)
        data.muted = !data.muted
        this.video.muted = data.muted
        this.videoDetails = data
      },
      // 全屏设置
      //进入全屏
      FullScreen() {
        const ele =  this.$refs.videoPlayer;
        if (ele.requestFullscreen) {
          ele.requestFullscreen();
        } else if (ele.mozRequestFullScreen) {
          ele.mozRequestFullScreen();
        } else if (ele.webkitRequestFullScreen) {
          ele.webkitRequestFullScreen();
        }
      },
      //退出全屏
      exitFullscreens() {
        const de = this.$refs.videoPlayer;
        if(de.exitFullscreen) {
          de.exitFullscreen();
        } else if(de.mozCancelFullScreen) {
          de.mozCancelFullScreen();
        } else if(de.webkitCancelFullScreen) {
          de.webkitCancelFullScreen();
        } else if(de.msExitFullscreen) {
          de.msExitFullscreen();
        }
      },
      // 打开全屏
      openFullScreen (){
        const data = Object.assign({}, this.videoDetails)
        data.isFullScreen = !data.isFullScreen
        if (data.isFullScreen) {
          this.FullScreen()
        } else {
          this.exitFullscreens()
        }
        this.videoDetails = data
      },
      createHls() {
        const that = this
        const video = this.$refs.video
        // 禁用鼠标右键
        video.oncontextmenu = () => false

        video.addEventListener('canplay', () => {
          video.play();
        })
        if (Hls.isSupported()) {
          this.hls = new Hls();
          this.hls.loadSource(this.option.src);
          this.hls.attachMedia(video);
          this.hls.on(Hls.Events.MANIFEST_PARSED, function () {
            that.play()
            that.getVideoDetails()
          });
        } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
          video.src = this.option.src;
          video.addEventListener('loadedmetadata', function () {
            that.play()
            that.getVideoDetails()
          });
        }
        this.video = video
      },
      createFlv() {
        const that = this
        const video = this.$refs.video;
        if (Flv.isSupported()) {
          video.oncontextmenu = () => false
          const flvPlayer = Flv.createPlayer({
            type: 'flv',
            cors: true,
            url: this.option.src
          });
          flvPlayer.attachMediaElement(video);
          flvPlayer.load();
          video.addEventListener('loadedmetadata', function () {
            that.play()
            that.getVideoDetails()
          });
        }
        this.video = video
      },
      getVideoType(url) {
        let type = 'flv'
        if (url.indexOf('.flv') !== -1) {
          type = 'flv'
        } else if (url.indexOf('.m3u8') !== -1) {
          type = 'hls'
        } else if (url.indexOf('.M3U8') !== -1) {
          type = 'hls'
        }
        return type
      }
    },
    mounted() {
      this.video = this.$refs.video
      this.getPcInfo()
      const type = this.getVideoType(this.options.src)
      switch (type) {
        case 'hls':
          this.createHls()
          break;
        case "flv":
          this.createFlv()
          break;
        default:

      }
    }
  };
</script>
<style scoped>
    .videoPlayer {
        width: 640px;
        height: 360px;
        position: relative;
        z-index: 99;
    }
    .videoPlayer:hover .pc_controls_box{
        display: block;
    }
    .videoPlayer * {
        -webkit-touch-callout: none; /* iOS Safari */

        -webkit-user-select: none; /* Chrome/Safari/Opera */

        -khtml-user-select: none; /* Konqueror */

        -moz-user-select: none; /* Firefox */

        -ms-user-select: none; /* Internet Explorer/Edge */

        user-select: none;
        /* Non-prefixed version, currently

       not supported by any browser */
    }

    .videoPlayer .pc_controls_box {
        display: none;
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 152px;
        background: linear-gradient(0deg, rgba(0, 0, 0, .5), rgba(0, 0, 0, 0));
    }

    .videoPlayer .pc_controls_box .pc_controls {
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 46px;
    }

    .videoPlayer .pc_controls_box .pc_controls .progress {
        position: absolute;
        /*top: 0;*/
        left: 0;
        background: rgba(255, 255, 255, 0.4);
        width: 100%;
        height: 3px;
        cursor: pointer;
        z-index: 10;
        bottom: 46px;
        transition: 0.5s;
    }
    .videoPlayer .pc_controls_box .pc_controls .progress:hover {
        height: 8px;
        transition: 0.5s;
    }
    .videoPlayer .pc_controls_box .pc_controls .progress .progress_spot {
        position: absolute;
        width: 12px;
        height: 12px;
        background: rgba(255, 255, 255, 1);
        border-radius: 50%;
        top: 50%;
        transform: translate(-6px, -50%);
        cursor: pointer;
        z-index: 1;
    }

    .videoPlayer .pc_controls_box .pc_controls .progress .progress_bar {
        position: absolute;
        top: 0;
        left: 0;
        background: rgba(34, 183, 254, 1);
        height: 100%;
        width: 0;
    }

    .videoPlayer .pc_controls_box .pc_controls .tool {
        position: absolute;
        width: 100%;
        height: 100%;
        left: 0;
        top: 0;
        display: flex;
        align-items: center;
    }

    .videoPlayer .pc_controls_box .pc_controls .tool .playBox {
        position: absolute;
        width: 19px;
        height: 22px;
        top: 50%;
        transform: translateY(-50%);
        left: 20px;
    }

    .videoPlayer .pc_controls_box .pc_controls .tool .playBox > div {
        width: 100%;
        height: 100%;
        cursor: pointer;
    }

    .videoPlayer .pc_controls_box .pc_controls .tool .playBox > div:nth-child(1) {
        background: url('./image/web/ico_bf_bf1.png') no-repeat;
        background-size: 100% 100%;
    }

    .videoPlayer .pc_controls_box .pc_controls .tool .playBox > div:nth-child(2) {
        background: url('./image/web/ico_bf_zt1.png') no-repeat;
        background-size: 100% 100%;
    }

    .videoPlayer .pc_controls_box .pc_controls .tool .timeBox {
        font-size: 14px;
        color: #fff;
        position: absolute;
        left: 61px;
    }

    .videoPlayer .pc_controls_box .pc_controls .tool .timeBox span:nth-child(2) {
        color: rgba(255, 255, 255, 0.6);
    }

    .videoPlayer .pc_controls_box .pc_controls .tool .speedBox {
        position: absolute;
        right: 105px;
        z-index: 11;
        font-size: 14px;
        height: 100%;
        display: flex;
        align-items: center;
    }

    .videoPlayer .pc_controls_box .pc_controls .tool .speedBox .speedBoxBtn {
        width: 90px;
        height: 30px;
        background: rgba(0, 0, 0, 0.4);
        border-radius: 15px;
        color: #fff;
        display: flex;
        justify-content: center;
        align-items: center;
        cursor: pointer;
    }

    .videoPlayer .pc_controls_box .pc_controls .tool .speedBox:hover .speedBoxBtn {
        color: #1FA7E8;
    }

    .videoPlayer .pc_controls_box .pc_controls .speedBox .speedList {
        position: absolute;
        bottom: 47px;
        z-index: 1;
        width: 90px;
        height: 166px;
        background: rgba(0, 0, 0, 0.8);
        border-radius: 6px;
        display: flex;
        flex-direction: column;
        justify-content: space-around;
        color: #fff;
        text-align: center;
    }

    .videoPlayer .pc_controls_box .pc_controls .speedBox .speedList > div {
        cursor: pointer;
    }

    .videoPlayer .pc_controls_box .pc_controls .speedBox .speedList > .active {
        color: #22B7FE;
    }

    .videoPlayer .pc_controls_box .pc_controls .volumeBox {
        position: absolute;
        height: 100%;
        top: 0;
        right: 62px;
        display: flex;
        align-items: center;
        width: 30px;
        justify-content: center;
        z-index: 11;
    }

    .videoPlayer .pc_controls_box .pc_controls .volumeBox .volumeBtn {
        background: url('./image/web/ico_bf_sy1.png') no-repeat;
        width: 22px;
        height: 18px;
        cursor: pointer;
        background-size: 100% 100%;
    }

    .videoPlayer .pc_controls_box .pc_controls .volumeBox .muted {
        background: url('./image/web/ico_bf_sy3.png') no-repeat;
        width: 22px;
        height: 18px;
        cursor: pointer;
        background-size: 100% 100%;
    }

    .videoPlayer .pc_controls_box .pc_controls .volumeBox:hover .volumeBtn {
        background: url('./image/web/ico_bf_sy2.png') no-repeat;
        background-size: 100% 100%;
    }

    .videoPlayer .pc_controls_box .pc_controls .volumeBox .volumeSetting {
        width: 30px;
        height: 166px;
        background: rgba(0, 0, 0, 0.8);
        border-radius: 6px;
        position: absolute;
        bottom: 46px;
        display: none;
        justify-content: center;
        align-items: center;
    }

    .videoPlayer .pc_controls_box .pc_controls .volumeBox:hover .volumeSetting {
        display: flex;
    }

    .videoPlayer .pc_controls_box .pc_controls .volumeBox .volumeSetting .lineBg {
        width: 4px;
        height: 146px;
        background: rgba(255, 255, 255, 0.4);
        border-radius: 2px;
        cursor: pointer;
        position: absolute;
    }

    .videoPlayer .pc_controls_box .pc_controls .volumeBox .volumeSetting .lineBg .line {
        position: absolute;
        left: 0;
        width: 100%;
        background: rgba(34, 183, 254, 1);
        border-radius: 2px;
        bottom: 0;
        cursor: pointer;
    }

    .videoPlayer .pc_controls_box .pc_controls .volumeBox .volumeSetting .lineBg .spot {
        position: absolute;
        left: 50%;
        bottom: 0;
        transform: translate(-50%, 50%);
        width: 10px;
        height: 10px;
        background: rgba(255, 255, 255, 1);
        border-radius: 50%;
        cursor: pointer;
    }

    .videoPlayer .pc_controls_box .pc_controls .fullScreenBox{
        width:18px;
        height:18px;
        border-radius:2px;
        position: absolute;
        right: 20px;
    }
    .videoPlayer .pc_controls_box .pc_controls .fullScreenBox>div{
        width:100%;
        height: 100%;
        cursor: pointer;
    }
    .videoPlayer .pc_controls_box .pc_controls .fullScreenBox>div:first-child{
        background: url("./image/web/ico_bf_fd1.png") no-repeat;
        background-size: 100% 100%;
    }
    .videoPlayer .pc_controls_box .pc_controls .fullScreenBox:active>div:first-child{
        background: url("./image/web/ico_bf_fd2.png") no-repeat;
        background-size: 100% 100%;
    }
    .videoPlayer .pc_controls_box .pc_controls .fullScreenBox>div:last-child{
        background: url("./image/web/ico_bf_sx1.png") no-repeat;
        background-size: 100% 100%;
    }
    .videoPlayer .pc_controls_box .pc_controls .fullScreenBox:active>div:last-child{
        background: url("./image/web/ico_bf_sx2.png") no-repeat;
        background-size: 100% 100%;
    }
    .videoPlayer.fullScreen{
        position: fixed;
        left: 0;
        top: 0;
        width: 100vw;
        height: 100vh;
    }

    video {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        outline: none;
        background: black;
    }
</style>
